import logging
from flask_restplus import Resource, Namespace, fields, marshal_with

from common.utils.backends import AliyunOssStorage
from common.utils.decorators import login_required
from flask import g, request, jsonify, Response
from app.models import db
from app import redis_clent, app
from flask_restplus import reqparse, inputs
from app.tasks.test import test
from app.routes.cost.schemas import RoadCostSchemas, RuelCostSchemas, ParkingCostSchemas
from common.utils.image_tools import delete_image
from .marshmallow import (
    RuelIdSerializer,
    RuelBodySerializer,
    RuelIdDeletedSerializer,
    RuelCreateQuerySerializer,
    RuelPutSerializer,
    RuelDataSerializer,
    RuelListQuerySerializer,
    ParkingDataSerializer,
    ParkingBodySerializer,
    ParkingListQuerySerializer,
    ParkingIdDeletedSerializer,
    ParkingCreateQuerySerializer,
    ParkingIdSerializer,
    ParkingPutSerializer,
    RoadDataSerializer,
    RoadBodySerializer,
    RoadPutSerializer,
    RoadIdDeletedSerializer,
    RoadListQuerySerializer,
    RoadCreateQuerySerializer,
    RoadIdSerializer,
    RuelImageIdSerizlizer,
    RuelImagePostQuerySerizlizer,
    RoadImageIdSerizlizer,
    RoadImagePostQuerySerizlizer,
    ParkingImageIdSerizlizer,
    ParkingImagePostQuerySerizlizer,
)
from ...models.parking_rate import ParkingRate, ParkingImage
from ...models.road_toll import RoadToll, RoadTollImage
from ...models.ruel_cost import RuelCost, RuelCostImage

LOG = logging.getLogger(__name__)

cost_ns = Namespace("cost")

ruel_cost_schemas = RuelCostSchemas(namespace=cost_ns)
road_cost_schemas = RoadCostSchemas(namespace=cost_ns)
parking_cost_schemas = ParkingCostSchemas(namespace=cost_ns)

ali_oss = AliyunOssStorage()


class RoadImageView(Resource):
    @cost_ns.expect(road_cost_schemas.RoadImageCreateSchemas())
    @cost_ns.marshal_with(road_cost_schemas.RoadImageIdSchemas())
    def post(self):
        image_query = RoadImagePostQuerySerizlizer()
        image_body = RoadImageIdSerizlizer()

        image_query.context["request"] = request

        image = image_query.load(data=request.form)
        response = image_body.dump(image)
        return response


class RoadImageDeleteView(Resource):
    def delete(self, id):

        try:
            image = RoadTollImage.query.get(id)
        except Exception as e:
            raise e
        delete_image(image.file)
        db.session.delete(image)
        db.session.commit()

        return Response(status=204 if image else 500)


class PakingImageView(Resource):
    @cost_ns.expect(parking_cost_schemas.ParkingImageCreateSchemas())
    @cost_ns.marshal_with(parking_cost_schemas.ParkingImageIdSchemas())
    def post(self):
        image_query = ParkingImagePostQuerySerizlizer()
        image_body = ParkingImageIdSerizlizer()

        image_query.context["request"] = request

        image = image_query.load(data=request.form)
        response = image_body.dump(image)
        return response


class ParkingImageDeleteView(Resource):
    def delete(self, id):

        try:
            image = ParkingImage.query.get(id)
        except Exception as e:
            raise e
        delete_image(image.file)
        db.session.delete(image)
        db.session.commit()

        return Response(status=204 if image else 500)


class RuelImageView(Resource):
    @cost_ns.expect(ruel_cost_schemas.RuelImageCreateSchemas())
    @cost_ns.marshal_with(ruel_cost_schemas.RuelImageIdSchemas())
    def post(self):
        image_query = RuelImagePostQuerySerizlizer()
        image_body = RuelImageIdSerizlizer()

        image_query.context["request"] = request

        image = image_query.load(data=request.form)
        response = image_body.dump(image)
        return response


class RuelImageDeleteView(Resource):
    def delete(self, id):

        try:
            image = RuelCostImage.query.get(id)
        except Exception as e:
            raise e
        delete_image(image.file)
        db.session.delete(image)
        db.session.commit()

        return Response(status=204 if image else 500)


class RuelCostListCreateView(Resource):

    """加油费"""

    # method_decorators = [login_required]

    @cost_ns.doc(params=ruel_cost_schemas.cost_list_query())
    @cost_ns.marshal_with(ruel_cost_schemas.cost_data())
    def get(self):
        ruel, total = RuelListQuerySerializer().load(data=request.args)
        response = RuelDataSerializer().dump({"total": total, "data": ruel})
        return response

    @cost_ns.expect(ruel_cost_schemas.cost_create_query())
    @cost_ns.marshal_with(ruel_cost_schemas.cost_id())
    def post(self):
        data = RuelCreateQuerySerializer().load(data=request.json)

        response = RuelIdSerializer().dump(data)
        return response


class RuelCostPutDeleteView(Resource):
    """加油费"""

    method_decorators = [login_required]

    @cost_ns.expect(ruel_cost_schemas.cost_create_query())
    def put(self, id):
        request.json["id"] = id
        data = RuelPutSerializer().load(data=request.json)

        return Response(status=202 if data == 1 else 500)

    def delete(self, id):
        data = RuelIdDeletedSerializer().load(data={"id": id})

        response = RuelIdSerializer().dump(data)
        return Response(status=204 if response else 500)

    @cost_ns.marshal_with(ruel_cost_schemas.cost_body())
    def get(self, id):
        # 查询记录详情
        try:
            ruel = RuelCost.query.get(id)
        except Exception as e:
            raise e

        response = RuelBodySerializer().dump(ruel)

        return response


class RoadCostListCreateView(Resource):
    """过路费"""

    method_decorators = [login_required]

    @cost_ns.doc(params=road_cost_schemas.cost_list_query())
    @cost_ns.marshal_with(road_cost_schemas.cost_data())
    def get(self):
        data, total = RoadListQuerySerializer().load(data=request.args)
        response = RoadDataSerializer().dump({"total": total, "data": data})
        return response
        pass

    @cost_ns.expect(road_cost_schemas.cost_create_query())
    @cost_ns.marshal_with(road_cost_schemas.cost_id())
    def post(self):
        data = RoadCreateQuerySerializer().load(data=request.json)

        response = RoadIdSerializer().dump(data)
        return response


class RoadCostPutDeleteView(Resource):
    """过路费"""

    method_decorators = [login_required]

    @cost_ns.expect(road_cost_schemas.cost_create_query())
    def put(self, id):
        request.json["id"] = id
        data = RoadPutSerializer().load(data=request.json)

        return Response(status=202 if data == 1 else 500)

    # @cost_ns.marshal_with(road_cost_schemas.cost_id())
    def delete(self, id):
        car_info = RoadIdDeletedSerializer().load(data={"id": id})

        response = RoadIdSerializer().dump(car_info)

        return Response(status=204 if response else 500)

    @cost_ns.marshal_with(road_cost_schemas.cost_body())
    def get(self, id):
        # 查询记录详情
        try:
            road = RoadToll.query.get(id)
        except Exception as e:
            raise e

        response = RoadBodySerializer().dump(road)

        return response


class ParkingCostListCreateView(Resource):
    """停车费"""

    method_decorators = [login_required]

    @cost_ns.doc(params=parking_cost_schemas.cost_list_query())
    @cost_ns.marshal_with(parking_cost_schemas.cost_data())
    def get(self):
        data, total = ParkingListQuerySerializer().load(data=request.args)
        response = ParkingDataSerializer().dump({"total": total, "data": data})
        return response

    @cost_ns.expect(parking_cost_schemas.cost_create_query())
    @cost_ns.marshal_with(parking_cost_schemas.cost_id())
    def post(self):
        data = ParkingCreateQuerySerializer().load(data=request.json)

        response = ParkingIdSerializer().dump(data)
        return response


class ParkingCostPutDeleteView(Resource):
    """停车费"""

    method_decorators = [login_required]

    @cost_ns.expect(parking_cost_schemas.cost_create_query())
    def put(self, id):
        request.json["id"] = id
        car_info = ParkingPutSerializer().load(data=request.json)

        return Response(status=202 if car_info == 1 else 500)

    def delete(self, id):
        data = ParkingIdDeletedSerializer().load(data={"id": id})

        response = ParkingIdSerializer().dump(data)
        return Response(status=204 if response else 500)

    @cost_ns.marshal_with(parking_cost_schemas.cost_body())
    def get(self, id):
        # 查询记录详情
        try:
            park = ParkingRate.query.get(id)
        except Exception as e:
            raise e

        response = ParkingBodySerializer().dump(park)

        return response
